This is to avoid everything depending on libsoup.
src/daemon/ot-daemon.c \
$(NULL)
-ostreed_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/daemon -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
-ostreed_LDADD = libotutil.la libostree.la $(OT_COREBIN_DEP_LIBS)
+ostreed_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/daemon -DLOCALEDIR=\"$(datadir)/locale\" $(OT_DEP_GIO_UNIX_CFLAGS)
+ostreed_LDADD = libotutil.la libostree.la $(OT_DEP_GIO_UNIX_LIBS)
src/libostree/ostree-checkout.c \
src/libostree/ostree-checkout.h \
$(NULL)
-libostree_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
-libostree_la_LIBADD = libotutil.la $(OT_COREBIN_DEP_LIBS)
+libostree_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_DEP_GIO_UNIX_CFLAGS)
+libostree_la_LIBADD = libotutil.la $(OT_DEP_GIO_UNIX_LIBS)
src/ostree/ot-builtin-remote.c \
src/ostree/ot-builtin-rev-parse.c \
src/ostree/ot-builtin-show.c \
+ src/ostree/ot-main.h \
+ src/ostree/ot-main.c \
$(NULL)
+ostree_bin_shared_cflags = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/ostree -DLOCALEDIR=\"$(datadir)/locale\"
+ostree_bin_shared_ldadd = libotutil.la libostree.la
+
+ostree_CFLAGS = $(ostree_bin_shared_cflags) $(OT_DEP_GIO_UNIX_CFLAGS)
+ostree_LDADD = $(ostree_bin_shared_ldadd) $(OT_DEP_GIO_UNIX_LIBS)
+
if USE_LIBSOUP_GNOME
-ostree_SOURCES += src/ostree/ot-builtin-pull.c
+bin_PROGRAMS += ostree-pull
+ostree_pull_SOURCES = src/ostree/ot-main.h \
+ src/ostree/ot-main.c \
+ src/ostree/ostree-pull.c
+
+ostree_pull_CFLAGS = $(ostree_bin_shared_cflags) $(OT_DEP_SOUP_CFLAGS)
+ostree_pull_LDADD = $(ostree_bin_shared_ldadd) $(OT_DEP_SOUP_LIBS)
endif
-ostree_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -I$(srcdir)/src/libostree -I$(srcdir)/src/ostree -DLOCALEDIR=\"$(datadir)/locale\" $(OT_COREBIN_DEP_CFLAGS)
-ostree_LDADD = libotutil.la libostree.la $(OT_COREBIN_DEP_LIBS)
+
src/libotutil/ot-glib-compat.h \
src/libotutil/otutil.h \
$(NULL)
-libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(GIO_UNIX_CFLAGS)
-libotutil_la_LIBADD = $(GIO_UNIX_LIBS)
+libotutil_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/src/libotutil -DLOCALEDIR=\"$(datadir)/locale\" $(OT_DEP_GIO_UNIX_CFLAGS)
+libotutil_la_LIBADD = $(OT_DEP_GIO_UNIX_LIBS)
PKG_PROG_PKG_CONFIG
GIO_DEPENDENCY="gio-unix-2.0 >= 2.28"
-PKG_CHECK_MODULES(GIO_UNIX, [gio-unix-2.0 >= 2.28])
+SOUP_DEPENDENCY="libsoup-gnome-2.4 >= 2.34.0"
+
+PKG_CHECK_MODULES(OT_DEP_GIO_UNIX, $GIO_DEPENDENCY)
+
AC_ARG_WITH(soup-gnome,
AS_HELP_STRING([--without-soup-gnome], [Do not use libsoup-gnome (implies no pull support)]),
:, with_soup_gnome=maybe)
if test x$with_soup_gnome != xno; then
- PKG_CHECK_MODULES(OT_COREBIN_DEP, [libsoup-gnome-2.4 >= 2.34.0 $GIO_DEPENDENCY], have_soup_gnome=yes, have_soup_gnome=no)
+ PKG_CHECK_EXISTS($SOUP_DEPENDENCY, have_soup_gnome=yes, have_soup_gnome=no)
if test x$have_soup_gnome = xno && test x$with_soup_gnome != xmaybe; then
AC_MSG_ERROR([libsoup-gnome is enabled but could not be found])
fi
if test x$have_soup_gnome = xyes; then
- AC_DEFINE([HAVE_LIBSOUP_GNOME], [1], [Define if we have libsoup-gnome])
+ PKG_CHECK_MODULES(OT_DEP_SOUP, $SOUP_DEPENDENCY)
else
- PKG_CHECK_MODULES(OT_COREBIN_DEP, [$GIO_DEPENDENCY])
with_soup_gnome=no
fi
-else
- PKG_CHECK_MODULES(OT_COREBIN_DEP, [$GIO_DEPENDENCY])
fi
AM_CONDITIONAL(USE_LIBSOUP_GNOME, test $with_soup_gnome != no)
--- /dev/null
+#!/usr/bin/python
+
+# Copyright (C) 2011 Colin Walters <walters@verbum.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+# ostbuild-compile-one-make wraps systems that implement the GNOME build API:
+# http://people.gnome.org/~walters/docs/build-api.txt
+
+import os,sys,subprocess,tempfile,re
+
+i=1
+repo=sys.argv[i]
+
+artifact_re = re.compile(r'^artifact-([^,]+)-([^,]+),(.+).tar.gz$')
+
+if os.getuid() != 0:
+ print "This program must be run as root."
+ sys.exit(1)
+
+def call_ostree_sync(*args):
+ subprocess.check_call(['ostree', '--repo=' + repo] + args)
+
+for arg in sys.argv[1:]:
+ match = artifact_re.match(arg)
+ if match is None
+ print "Invalid artifact name: %s" % (arg, )
+ sys.exit(1)
+ arch = match.group(1)
+ name = match.group(2)
+ version = match.group(3)
+
+ branch_name = 'artifact-%s-%s' % (arch, name)
+
+ call_ostree_sync('commit', '-b', branch_name, '-s', version,
+
--- /dev/null
+#!/bin/sh
+#
+# Copyright (C) 2011 Colin Walters <walters@verbum.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+#
+# Author: Colin Walters <walters@verbum.org>
+
+
+bn=$(basename $(pwd))
+ostbuild-nice-and-log-output "compile-${bn}.log" ostbuild-chroot-compile-one-impl "$@"
--- /dev/null
+#!/usr/bin/python
+
+# Copyright (C) 2011 Colin Walters <walters@verbum.org>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+
+import os,sys,re,subprocess
+
+i=1
+repo=sys.argv[i]
+i += 1
+chroot_path=sys.argv[i]
+i += 1
+args=sys.argv[i:]
+
+if os.getuid() != 0:
+ print "This program must be run as root."
+ sys.exit(1)
+
+rootdir=os.path.join(chroot_path, 'root')
+
+if not os.path.isdir(rootdir):
+ print "Not a directory: %s" % (rootdir, )
+ sys.exit(1)
+
+builddir = os.path.join(rootdir, 'ostree-build')
+if not os.path.isdir(builddir):
+ os.mkdir(builddir)
+
+
+def run_in_chroot(args):
+ proc_path=os.path.join(chroot_path, 'proc')
+ subprocess.check_call(['mount', '-t', 'proc', 'proc', proc_path])
+
+ try:
+ subprocess.check_call(['chroot', chroot_path])
+ finally:
+ subprocess.call(['umount', proc_path])
+
+run_in_chroot(args)
#include <string.h>
+#include "ot-main.h"
#include "ot-builtins.h"
static OstreeBuiltin builtins[] = {
{ "local-clone", ostree_builtin_local_clone, 0 },
{ "log", ostree_builtin_log, 0 },
{ "ls", ostree_builtin_ls, 0 },
-#ifdef HAVE_LIBSOUP_GNOME
- { "pull", ostree_builtin_pull, 0 },
-#endif
{ "fsck", ostree_builtin_fsck, 0 },
{ "remote", ostree_builtin_remote, 0 },
{ "rev-parse", ostree_builtin_rev_parse, 0 },
{ NULL }
};
-static int
-usage (char **argv, gboolean is_error)
-{
- OstreeBuiltin *builtin = builtins;
- void (*print_func) (const gchar *format, ...);
-
- if (is_error)
- print_func = g_printerr;
- else
- print_func = g_print;
-
- print_func ("usage: %s --repo=PATH COMMAND [options]\n",
- argv[0]);
- print_func ("Builtin commands:\n");
-
- while (builtin->name)
- {
- print_func (" %s\n", builtin->name);
- builtin++;
- }
- return (is_error ? 1 : 0);
-}
-
-static void
-prep_builtin_argv (const char *builtin,
- int argc,
- char **argv,
- int *out_argc,
- char ***out_argv)
-{
- int i;
- char **cmd_argv;
-
- cmd_argv = g_new0 (char *, argc + 2);
-
- cmd_argv[0] = (char*)builtin;
- for (i = 0; i < argc; i++)
- cmd_argv[i+1] = argv[i];
- cmd_argv[i+1] = NULL;
- *out_argc = argc+1;
- *out_argv = cmd_argv;
-}
-
-static void
-set_error_print_usage (GError **error, const char *msg, char **argv)
-{
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, msg);
- usage (argv, TRUE);
-}
-
int
main (int argc,
char **argv)
{
- OstreeBuiltin *builtin;
- GError *error = NULL;
- int cmd_argc;
- char **cmd_argv = NULL;
- gboolean am_root;
- gboolean have_repo_arg;
- const char *cmd = NULL;
- const char *repo = NULL;
-
- g_type_init ();
-
- g_set_prgname (argv[0]);
-
- if (argc < 2)
- return usage (argv, 1);
-
- am_root = getuid () == 0;
- have_repo_arg = g_str_has_prefix (argv[1], "--repo=");
-
- if (!have_repo_arg && am_root)
- repo = "/sysroot/ostree/repo";
- else if (have_repo_arg)
- repo = argv[1] + strlen ("--repo=");
- else
- repo = NULL;
-
- if (!have_repo_arg)
- cmd = argv[1];
- else
- cmd = argv[2];
-
- builtin = builtins;
- while (builtin->name)
- {
- if (strcmp (cmd, builtin->name) == 0)
- break;
- builtin++;
- }
-
- if (!builtin)
- {
- set_error_print_usage (&error, "Unknown command", argv);
- goto out;
- }
-
- if (repo == NULL && !(builtin->flags & OSTREE_BUILTIN_FLAG_NO_REPO))
- {
- set_error_print_usage (&error, "Command requires a --repo argument", argv);
- goto out;
- }
-
- if (!have_repo_arg)
- prep_builtin_argv (cmd, argc-2, argv+2, &cmd_argc, &cmd_argv);
- else
- prep_builtin_argv (cmd, argc-3, argv+3, &cmd_argc, &cmd_argv);
-
- if (!builtin->fn (cmd_argc, cmd_argv, repo, &error))
- goto out;
-
- out:
- g_free (cmd_argv);
- if (error)
- {
- g_printerr ("%s\n", error->message);
- g_clear_error (&error);
- return 1;
- }
- return 0;
+ return ostree_main (argc, argv, builtins);
}
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters@verbum.org>
+ */
+
+#include "config.h"
+
+#include <libsoup/soup-gnome.h>
+
+#include "ostree.h"
+#include "ot-main.h"
+
+gboolean verbose;
+
+static GOptionEntry options[] = {
+ { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Show more information", NULL },
+};
+
+static void
+log_verbose (const char *fmt,
+ ...) G_GNUC_PRINTF (1, 2);
+
+static void
+log_verbose (const char *fmt,
+ ...)
+{
+ va_list args;
+ char *msg;
+
+ if (!verbose)
+ return;
+
+ va_start (args, fmt);
+
+ msg = g_strdup_vprintf (fmt, args);
+ g_print ("%s\n", msg);
+ g_free (msg);
+}
+
+static gboolean
+fetch_uri (OstreeRepo *repo,
+ SoupSession *soup,
+ SoupURI *uri,
+ char **temp_filename,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ SoupMessage *msg = NULL;
+ guint response;
+ char *template = NULL;
+ int fd;
+ SoupBuffer *buf = NULL;
+ GFile *tempf = NULL;
+ char *uri_string = NULL;
+
+ uri_string = soup_uri_to_string (uri, FALSE);
+ log_verbose ("Fetching %s", uri_string);
+ msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
+
+ response = soup_session_send_message (soup, msg);
+ if (response != 200)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to retrieve '%s': %d %s",
+ uri_string, response, msg->reason_phrase);
+ goto out;
+ }
+
+ template = g_strdup_printf ("%s/tmp-fetchXXXXXX", ostree_repo_get_path (repo));
+
+ fd = g_mkstemp (template);
+ if (fd < 0)
+ {
+ ot_util_set_error_from_errno (error, errno);
+ goto out;
+ }
+ close (fd);
+ tempf = ot_gfile_new_for_path (template);
+
+ buf = soup_message_body_flatten (msg->response_body);
+
+ if (!g_file_replace_contents (tempf, buf->data, buf->length, NULL, FALSE, 0, NULL, NULL, error))
+ goto out;
+
+ *temp_filename = template;
+ template = NULL;
+
+ ret = TRUE;
+ out:
+ g_free (uri_string);
+ g_free (template);
+ g_clear_object (&msg);
+ g_clear_object (&tempf);
+ return ret;
+}
+
+static gboolean
+store_object (OstreeRepo *repo,
+ SoupSession *soup,
+ SoupURI *baseuri,
+ const char *object,
+ OstreeObjectType objtype,
+ gboolean *did_exist,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ char *filename = NULL;
+ char *objpath = NULL;
+ char *relpath = NULL;
+ SoupURI *obj_uri = NULL;
+
+ objpath = ostree_get_relative_object_path (object, objtype, TRUE);
+ obj_uri = soup_uri_copy (baseuri);
+ relpath = g_build_filename (soup_uri_get_path (obj_uri), objpath, NULL);
+ soup_uri_set_path (obj_uri, relpath);
+
+ if (!fetch_uri (repo, soup, obj_uri, &filename, error))
+ goto out;
+
+ if (!ostree_repo_store_packfile (repo, object, filename, objtype, did_exist, error))
+ goto out;
+
+ ret = TRUE;
+ out:
+ if (obj_uri)
+ soup_uri_free (obj_uri);
+ if (filename)
+ (void) unlink (filename);
+ g_free (filename);
+ g_free (objpath);
+ g_free (relpath);
+ return ret;
+}
+
+static gboolean
+store_tree_recurse (OstreeRepo *repo,
+ SoupSession *soup,
+ SoupURI *base_uri,
+ const char *rev,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GVariant *tree = NULL;
+ GVariant *files_variant = NULL;
+ GVariant *dirs_variant = NULL;
+ OstreeSerializedVariantType metatype;
+ gboolean did_exist;
+ int i, n;
+
+ if (!store_object (repo, soup, base_uri, rev, OSTREE_OBJECT_TYPE_META, &did_exist, error))
+ goto out;
+
+ if (did_exist)
+ log_verbose ("Already have tree %s", rev);
+ else
+ {
+ if (!ostree_repo_load_variant (repo, rev, &metatype, &tree, error))
+ goto out;
+
+ if (metatype != OSTREE_SERIALIZED_TREE_VARIANT)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Tree metadata '%s' has wrong type %d, expected %d",
+ rev, metatype, OSTREE_SERIALIZED_TREE_VARIANT);
+ goto out;
+ }
+
+ /* PARSE OSTREE_SERIALIZED_TREE_VARIANT */
+ files_variant = g_variant_get_child_value (tree, 2);
+ dirs_variant = g_variant_get_child_value (tree, 3);
+
+ n = g_variant_n_children (files_variant);
+ for (i = 0; i < n; i++)
+ {
+ const char *filename;
+ const char *checksum;
+
+ g_variant_get_child (files_variant, i, "(&s&s)", &filename, &checksum);
+
+ if (!store_object (repo, soup, base_uri, checksum, OSTREE_OBJECT_TYPE_FILE, &did_exist, error))
+ goto out;
+ }
+
+ n = g_variant_n_children (dirs_variant);
+ for (i = 0; i < n; i++)
+ {
+ const char *dirname;
+ const char *tree_checksum;
+ const char *meta_checksum;
+
+ g_variant_get_child (dirs_variant, i, "(&s&s&s)",
+ &dirname, &tree_checksum, &meta_checksum);
+
+ if (!store_object (repo, soup, base_uri, meta_checksum, OSTREE_OBJECT_TYPE_META, &did_exist, error))
+ goto out;
+
+ if (!store_tree_recurse (repo, soup, base_uri, tree_checksum, error))
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+ out:
+ ot_clear_gvariant (&tree);
+ ot_clear_gvariant (&files_variant);
+ ot_clear_gvariant (&dirs_variant);
+ return ret;
+}
+
+static gboolean
+store_commit_recurse (OstreeRepo *repo,
+ SoupSession *soup,
+ SoupURI *base_uri,
+ const char *rev,
+ GError **error)
+{
+ gboolean ret = FALSE;
+ GVariant *commit = NULL;
+ OstreeSerializedVariantType metatype;
+ const char *tree_contents_checksum;
+ const char *tree_meta_checksum;
+ gboolean did_exist;
+
+ if (!store_object (repo, soup, base_uri, rev, OSTREE_OBJECT_TYPE_META, &did_exist, error))
+ goto out;
+
+ if (did_exist)
+ log_verbose ("Already have commit %s", rev);
+ else
+ {
+ if (!ostree_repo_load_variant (repo, rev, &metatype, &commit, error))
+ goto out;
+
+ if (metatype != OSTREE_SERIALIZED_COMMIT_VARIANT)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Commit '%s' has wrong type %d, expected %d",
+ rev, metatype, OSTREE_SERIALIZED_COMMIT_VARIANT);
+ goto out;
+ }
+
+ /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */
+ g_variant_get_child (commit, 6, "&s", &tree_contents_checksum);
+ g_variant_get_child (commit, 7, "&s", &tree_meta_checksum);
+
+ if (!store_object (repo, soup, base_uri, tree_meta_checksum, OSTREE_OBJECT_TYPE_META, &did_exist, error))
+ goto out;
+
+ if (!store_tree_recurse (repo, soup, base_uri, tree_contents_checksum, error))
+ goto out;
+ }
+
+ ret = TRUE;
+ out:
+ ot_clear_gvariant (&commit);
+ return ret;
+}
+
+static gboolean
+ostree_builtin_pull (int argc, char **argv, const char *repo_path, GError **error)
+{
+ GOptionContext *context;
+ gboolean ret = FALSE;
+ OstreeRepo *repo = NULL;
+ const char *remote;
+ const char *branch;
+ char *remote_branch_ref_path = NULL;
+ char *key = NULL;
+ char *baseurl = NULL;
+ char *refpath = NULL;
+ char *temppath = NULL;
+ GFile *tempf = NULL;
+ char *remote_ref = NULL;
+ char *original_rev = NULL;
+ GKeyFile *config = NULL;
+ SoupURI *base_uri = NULL;
+ SoupURI *target_uri = NULL;
+ SoupSession *soup = NULL;
+ char *rev = NULL;
+
+ context = g_option_context_new ("REMOTE BRANCH - Download data from remote repository");
+ g_option_context_add_main_entries (context, options, NULL);
+
+ if (!g_option_context_parse (context, &argc, &argv, error))
+ goto out;
+
+ repo = ostree_repo_new (repo_path);
+ if (!ostree_repo_check (repo, error))
+ goto out;
+
+ if (argc < 3)
+ {
+ ot_util_usage_error (context, "REMOTE and BRANCH must be specified", error);
+ goto out;
+ }
+
+ remote = argv[1];
+ branch = argv[2];
+
+ remote_ref = g_strdup_printf ("%s/%s", remote, branch);
+
+ if (!ostree_repo_resolve_rev (repo, remote_ref, TRUE, &original_rev, error))
+ goto out;
+
+ config = ostree_repo_get_config (repo);
+
+ key = g_strdup_printf ("remote \"%s\"", remote);
+ baseurl = g_key_file_get_string (config, key, "url", error);
+ if (!baseurl)
+ goto out;
+ base_uri = soup_uri_new (baseurl);
+ if (!base_uri)
+ {
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ "Failed to parse url '%s'", baseurl);
+ goto out;
+ }
+ target_uri = soup_uri_copy (base_uri);
+ g_free (refpath);
+ refpath = g_build_filename (soup_uri_get_path (target_uri), "refs", "heads", branch, NULL);
+ soup_uri_set_path (target_uri, refpath);
+
+ soup = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT, "ostree ",
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER,
+ SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_COOKIE_JAR,
+ NULL);
+ if (!fetch_uri (repo, soup, target_uri, &temppath, error))
+ goto out;
+ tempf = ot_gfile_new_for_path (temppath);
+
+ if (!ot_gfile_load_contents_utf8 (tempf, &rev, NULL, NULL, error))
+ goto out;
+ g_strchomp (rev);
+
+ if (original_rev && strcmp (rev, original_rev) == 0)
+ {
+ g_print ("No changes in %s\n", remote_ref);
+ }
+ else
+ {
+ if (!ostree_validate_checksum_string (rev, error))
+ goto out;
+
+ if (!store_commit_recurse (repo, soup, base_uri, rev, error))
+ goto out;
+
+ if (!ostree_repo_write_ref (repo, remote, branch, rev, error))
+ goto out;
+
+ g_print ("remote %s is now %s\n", remote_ref, rev);
+ }
+
+ ret = TRUE;
+ out:
+ if (context)
+ g_option_context_free (context);
+ if (temppath)
+ (void) unlink (temppath);
+ g_free (temppath);
+ g_free (key);
+ g_free (rev);
+ g_free (remote_ref);
+ g_free (original_rev);
+ g_free (baseurl);
+ g_free (refpath);
+ g_free (remote_branch_ref_path);
+ g_clear_object (&soup);
+ if (base_uri)
+ soup_uri_free (base_uri);
+ if (target_uri)
+ soup_uri_free (target_uri);
+ g_clear_object (&repo);
+ g_clear_object (&soup);
+ return ret;
+}
+
+static OstreeBuiltin builtins[] = {
+ { "pull", ostree_builtin_pull, 0 },
+ { NULL }
+};
+
+int
+main (int argc,
+ char **argv)
+{
+ return ostree_main (argc, argv, builtins);
+}
+++ /dev/null
-/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
- *
- * Copyright (C) 2011 Colin Walters <walters@verbum.org>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- *
- * Author: Colin Walters <walters@verbum.org>
- */
-
-#include "config.h"
-
-#include "ot-builtins.h"
-#include "ostree.h"
-
-#include <glib/gi18n.h>
-
-#include <libsoup/soup-gnome.h>
-
-gboolean verbose;
-
-static GOptionEntry options[] = {
- { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Show more information", NULL },
-};
-
-static void
-log_verbose (const char *fmt,
- ...) G_GNUC_PRINTF (1, 2);
-
-static void
-log_verbose (const char *fmt,
- ...)
-{
- va_list args;
- char *msg;
-
- if (!verbose)
- return;
-
- va_start (args, fmt);
-
- msg = g_strdup_vprintf (fmt, args);
- g_print ("%s\n", msg);
- g_free (msg);
-}
-
-static gboolean
-fetch_uri (OstreeRepo *repo,
- SoupSession *soup,
- SoupURI *uri,
- char **temp_filename,
- GError **error)
-{
- gboolean ret = FALSE;
- SoupMessage *msg = NULL;
- guint response;
- char *template = NULL;
- int fd;
- SoupBuffer *buf = NULL;
- GFile *tempf = NULL;
- char *uri_string = NULL;
-
- uri_string = soup_uri_to_string (uri, FALSE);
- log_verbose ("Fetching %s", uri_string);
- msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
-
- response = soup_session_send_message (soup, msg);
- if (response != 200)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to retrieve '%s': %d %s",
- uri_string, response, msg->reason_phrase);
- goto out;
- }
-
- template = g_strdup_printf ("%s/tmp-fetchXXXXXX", ostree_repo_get_path (repo));
-
- fd = g_mkstemp (template);
- if (fd < 0)
- {
- ot_util_set_error_from_errno (error, errno);
- goto out;
- }
- close (fd);
- tempf = ot_gfile_new_for_path (template);
-
- buf = soup_message_body_flatten (msg->response_body);
-
- if (!g_file_replace_contents (tempf, buf->data, buf->length, NULL, FALSE, 0, NULL, NULL, error))
- goto out;
-
- *temp_filename = template;
- template = NULL;
-
- ret = TRUE;
- out:
- g_free (uri_string);
- g_free (template);
- g_clear_object (&msg);
- g_clear_object (&tempf);
- return ret;
-}
-
-static gboolean
-store_object (OstreeRepo *repo,
- SoupSession *soup,
- SoupURI *baseuri,
- const char *object,
- OstreeObjectType objtype,
- gboolean *did_exist,
- GError **error)
-{
- gboolean ret = FALSE;
- char *filename = NULL;
- char *objpath = NULL;
- char *relpath = NULL;
- SoupURI *obj_uri = NULL;
-
- objpath = ostree_get_relative_object_path (object, objtype, TRUE);
- obj_uri = soup_uri_copy (baseuri);
- relpath = g_build_filename (soup_uri_get_path (obj_uri), objpath, NULL);
- soup_uri_set_path (obj_uri, relpath);
-
- if (!fetch_uri (repo, soup, obj_uri, &filename, error))
- goto out;
-
- if (!ostree_repo_store_packfile (repo, object, filename, objtype, did_exist, error))
- goto out;
-
- ret = TRUE;
- out:
- if (obj_uri)
- soup_uri_free (obj_uri);
- if (filename)
- (void) unlink (filename);
- g_free (filename);
- g_free (objpath);
- g_free (relpath);
- return ret;
-}
-
-static gboolean
-store_tree_recurse (OstreeRepo *repo,
- SoupSession *soup,
- SoupURI *base_uri,
- const char *rev,
- GError **error)
-{
- gboolean ret = FALSE;
- GVariant *tree = NULL;
- GVariant *files_variant = NULL;
- GVariant *dirs_variant = NULL;
- OstreeSerializedVariantType metatype;
- gboolean did_exist;
- int i, n;
-
- if (!store_object (repo, soup, base_uri, rev, OSTREE_OBJECT_TYPE_META, &did_exist, error))
- goto out;
-
- if (did_exist)
- log_verbose ("Already have tree %s", rev);
- else
- {
- if (!ostree_repo_load_variant (repo, rev, &metatype, &tree, error))
- goto out;
-
- if (metatype != OSTREE_SERIALIZED_TREE_VARIANT)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Tree metadata '%s' has wrong type %d, expected %d",
- rev, metatype, OSTREE_SERIALIZED_TREE_VARIANT);
- goto out;
- }
-
- /* PARSE OSTREE_SERIALIZED_TREE_VARIANT */
- files_variant = g_variant_get_child_value (tree, 2);
- dirs_variant = g_variant_get_child_value (tree, 3);
-
- n = g_variant_n_children (files_variant);
- for (i = 0; i < n; i++)
- {
- const char *filename;
- const char *checksum;
-
- g_variant_get_child (files_variant, i, "(&s&s)", &filename, &checksum);
-
- if (!store_object (repo, soup, base_uri, checksum, OSTREE_OBJECT_TYPE_FILE, &did_exist, error))
- goto out;
- }
-
- n = g_variant_n_children (dirs_variant);
- for (i = 0; i < n; i++)
- {
- const char *dirname;
- const char *tree_checksum;
- const char *meta_checksum;
-
- g_variant_get_child (dirs_variant, i, "(&s&s&s)",
- &dirname, &tree_checksum, &meta_checksum);
-
- if (!store_object (repo, soup, base_uri, meta_checksum, OSTREE_OBJECT_TYPE_META, &did_exist, error))
- goto out;
-
- if (!store_tree_recurse (repo, soup, base_uri, tree_checksum, error))
- goto out;
- }
- }
-
- ret = TRUE;
- out:
- ot_clear_gvariant (&tree);
- ot_clear_gvariant (&files_variant);
- ot_clear_gvariant (&dirs_variant);
- return ret;
-}
-
-static gboolean
-store_commit_recurse (OstreeRepo *repo,
- SoupSession *soup,
- SoupURI *base_uri,
- const char *rev,
- GError **error)
-{
- gboolean ret = FALSE;
- GVariant *commit = NULL;
- OstreeSerializedVariantType metatype;
- const char *tree_contents_checksum;
- const char *tree_meta_checksum;
- gboolean did_exist;
-
- if (!store_object (repo, soup, base_uri, rev, OSTREE_OBJECT_TYPE_META, &did_exist, error))
- goto out;
-
- if (did_exist)
- log_verbose ("Already have commit %s", rev);
- else
- {
- if (!ostree_repo_load_variant (repo, rev, &metatype, &commit, error))
- goto out;
-
- if (metatype != OSTREE_SERIALIZED_COMMIT_VARIANT)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Commit '%s' has wrong type %d, expected %d",
- rev, metatype, OSTREE_SERIALIZED_COMMIT_VARIANT);
- goto out;
- }
-
- /* PARSE OSTREE_SERIALIZED_COMMIT_VARIANT */
- g_variant_get_child (commit, 6, "&s", &tree_contents_checksum);
- g_variant_get_child (commit, 7, "&s", &tree_meta_checksum);
-
- if (!store_object (repo, soup, base_uri, tree_meta_checksum, OSTREE_OBJECT_TYPE_META, &did_exist, error))
- goto out;
-
- if (!store_tree_recurse (repo, soup, base_uri, tree_contents_checksum, error))
- goto out;
- }
-
- ret = TRUE;
- out:
- ot_clear_gvariant (&commit);
- return ret;
-}
-
-gboolean
-ostree_builtin_pull (int argc, char **argv, const char *repo_path, GError **error)
-{
- GOptionContext *context;
- gboolean ret = FALSE;
- OstreeRepo *repo = NULL;
- const char *remote;
- const char *branch;
- char *remote_branch_ref_path = NULL;
- char *key = NULL;
- char *baseurl = NULL;
- char *refpath = NULL;
- char *temppath = NULL;
- GFile *tempf = NULL;
- char *remote_ref = NULL;
- char *original_rev = NULL;
- GKeyFile *config = NULL;
- SoupURI *base_uri = NULL;
- SoupURI *target_uri = NULL;
- SoupSession *soup = NULL;
- char *rev = NULL;
-
- context = g_option_context_new ("REMOTE BRANCH - Download data from remote repository");
- g_option_context_add_main_entries (context, options, NULL);
-
- if (!g_option_context_parse (context, &argc, &argv, error))
- goto out;
-
- repo = ostree_repo_new (repo_path);
- if (!ostree_repo_check (repo, error))
- goto out;
-
- if (argc < 3)
- {
- ot_util_usage_error (context, "REMOTE and BRANCH must be specified", error);
- goto out;
- }
-
- remote = argv[1];
- branch = argv[2];
-
- remote_ref = g_strdup_printf ("%s/%s", remote, branch);
-
- if (!ostree_repo_resolve_rev (repo, remote_ref, TRUE, &original_rev, error))
- goto out;
-
- config = ostree_repo_get_config (repo);
-
- key = g_strdup_printf ("remote \"%s\"", remote);
- baseurl = g_key_file_get_string (config, key, "url", error);
- if (!baseurl)
- goto out;
- base_uri = soup_uri_new (baseurl);
- if (!base_uri)
- {
- g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
- "Failed to parse url '%s'", baseurl);
- goto out;
- }
- target_uri = soup_uri_copy (base_uri);
- g_free (refpath);
- refpath = g_build_filename (soup_uri_get_path (target_uri), "refs", "heads", branch, NULL);
- soup_uri_set_path (target_uri, refpath);
-
- soup = soup_session_sync_new_with_options (SOUP_SESSION_USER_AGENT, "ostree ",
- SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
- SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_DECODER,
- SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_COOKIE_JAR,
- NULL);
- if (!fetch_uri (repo, soup, target_uri, &temppath, error))
- goto out;
- tempf = ot_gfile_new_for_path (temppath);
-
- if (!ot_gfile_load_contents_utf8 (tempf, &rev, NULL, NULL, error))
- goto out;
- g_strchomp (rev);
-
- if (original_rev && strcmp (rev, original_rev) == 0)
- {
- g_print ("No changes in %s\n", remote_ref);
- }
- else
- {
- if (!ostree_validate_checksum_string (rev, error))
- goto out;
-
- if (!store_commit_recurse (repo, soup, base_uri, rev, error))
- goto out;
-
- if (!ostree_repo_write_ref (repo, remote, branch, rev, error))
- goto out;
-
- g_print ("remote %s is now %s\n", remote_ref, rev);
- }
-
- ret = TRUE;
- out:
- if (context)
- g_option_context_free (context);
- if (temppath)
- (void) unlink (temppath);
- g_free (temppath);
- g_free (key);
- g_free (rev);
- g_free (remote_ref);
- g_free (original_rev);
- g_free (baseurl);
- g_free (refpath);
- g_free (remote_branch_ref_path);
- g_clear_object (&soup);
- if (base_uri)
- soup_uri_free (base_uri);
- if (target_uri)
- soup_uri_free (target_uri);
- g_clear_object (&repo);
- g_clear_object (&soup);
- return ret;
-}
G_BEGIN_DECLS
-typedef enum {
- OSTREE_BUILTIN_FLAG_NONE = 0,
- OSTREE_BUILTIN_FLAG_NO_REPO = 1,
-} OstreeBuiltinFlags;
-
-typedef struct {
- const char *name;
- gboolean (*fn) (int argc, char **argv, const char *repo, GError **error);
- int flags; /* OstreeBuiltinFlags */
-} OstreeBuiltin;
-
gboolean ostree_builtin_checkout (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_checksum (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_commit (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_local_clone (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_log (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_ls (int argc, char **argv, const char *repo, GError **error);
-gboolean ostree_builtin_pull (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_run_triggers (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_fsck (int argc, char **argv, const char *repo, GError **error);
gboolean ostree_builtin_show (int argc, char **argv, const char *repo, GError **error);
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters@verbum.org>
+ */
+
+#include "config.h"
+
+#include <gio/gio.h>
+
+#include <string.h>
+
+#include "ot-main.h"
+
+static int
+usage (char **argv, OstreeBuiltin *builtins, gboolean is_error)
+{
+ OstreeBuiltin *builtin = builtins;
+ void (*print_func) (const gchar *format, ...);
+
+ if (is_error)
+ print_func = g_printerr;
+ else
+ print_func = g_print;
+
+ print_func ("usage: %s --repo=PATH COMMAND [options]\n",
+ argv[0]);
+ print_func ("Builtin commands:\n");
+
+ while (builtin->name)
+ {
+ print_func (" %s\n", builtin->name);
+ builtin++;
+ }
+ return (is_error ? 1 : 0);
+}
+
+static void
+prep_builtin_argv (const char *builtin,
+ int argc,
+ char **argv,
+ int *out_argc,
+ char ***out_argv)
+{
+ int i;
+ char **cmd_argv;
+
+ cmd_argv = g_new0 (char *, argc + 2);
+
+ cmd_argv[0] = (char*)builtin;
+ for (i = 0; i < argc; i++)
+ cmd_argv[i+1] = argv[i];
+ cmd_argv[i+1] = NULL;
+ *out_argc = argc+1;
+ *out_argv = cmd_argv;
+}
+
+static void
+set_error_print_usage (GError **error, OstreeBuiltin *builtins, const char *msg, char **argv)
+{
+ g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, msg);
+ usage (argv, builtins, TRUE);
+}
+
+int
+ostree_main (int argc,
+ char **argv,
+ OstreeBuiltin *builtins)
+{
+ OstreeBuiltin *builtin;
+ GError *error = NULL;
+ int cmd_argc;
+ char **cmd_argv = NULL;
+ gboolean am_root;
+ gboolean have_repo_arg;
+ const char *cmd = NULL;
+ const char *repo = NULL;
+ int arg_off;
+
+ g_type_init ();
+
+ g_set_prgname (argv[0]);
+
+ if (argc < 2)
+ return usage (argv, builtins, 1);
+
+ am_root = getuid () == 0;
+ have_repo_arg = g_str_has_prefix (argv[1], "--repo=");
+
+ if (!have_repo_arg && am_root)
+ repo = "/sysroot/ostree/repo";
+ else if (have_repo_arg)
+ repo = argv[1] + strlen ("--repo=");
+ else
+ repo = NULL;
+
+ cmd = strchr (argv[0], '-');
+ if (cmd)
+ {
+ cmd += 1;
+ arg_off = 1;
+ if (have_repo_arg)
+ arg_off += 1;
+ }
+ else if (!have_repo_arg)
+ {
+ arg_off = 2;
+ cmd = argv[arg_off-1];
+ }
+ else
+ {
+ arg_off = 3;
+ cmd = argv[arg_off-1];
+ }
+
+ builtin = builtins;
+ while (builtin->name)
+ {
+ if (strcmp (cmd, builtin->name) == 0)
+ break;
+ builtin++;
+ }
+
+ if (!builtin->name)
+ {
+ set_error_print_usage (&error, builtins, "Unknown command", argv);
+ goto out;
+ }
+
+ if (repo == NULL && !(builtin->flags & OSTREE_BUILTIN_FLAG_NO_REPO))
+ {
+ set_error_print_usage (&error, builtins, "Command requires a --repo argument", argv);
+ goto out;
+ }
+
+ prep_builtin_argv (cmd, argc-arg_off, argv+arg_off, &cmd_argc, &cmd_argv);
+
+ if (!builtin->fn (cmd_argc, cmd_argv, repo, &error))
+ goto out;
+
+ out:
+ g_free (cmd_argv);
+ if (error)
+ {
+ g_printerr ("%s\n", error->message);
+ g_clear_error (&error);
+ return 1;
+ }
+ return 0;
+}
--- /dev/null
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*-
+ *
+ * Copyright (C) 2011 Colin Walters <walters@verbum.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Colin Walters <walters@verbum.org>
+ */
+
+#include <gio/gio.h>
+
+typedef enum {
+ OSTREE_BUILTIN_FLAG_NONE = 0,
+ OSTREE_BUILTIN_FLAG_NO_REPO = 1,
+} OstreeBuiltinFlags;
+
+typedef struct {
+ const char *name;
+ gboolean (*fn) (int argc, char **argv, const char *repo, GError **error);
+ int flags; /* OstreeBuiltinFlags */
+} OstreeBuiltin;
+
+int ostree_main (int argc, char **argv, OstreeBuiltin *builtins);
+
setup_fake_remote_repo1
cd ${test_tmpdir}
mkdir repo
-$OSTREE init
-$OSTREE remote add origin $(cat httpd-address)/ostree/gnomerepo
-$OSTREE pull origin main
+ostree --repo=repo init
+ostree --repo=repo remote add origin $(cat httpd-address)/ostree/gnomerepo
+ostree-pull --repo=repo origin main
echo "ok pull"
cd ${test_tmpdir}